﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceProcess;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using PSE.Deployment.Util;

namespace PSE.Deployment.ConfigurationManager.Controls
{
    public class ServiceControl : Control
    {
        string _serviceDisplayName;
        string _serviceName;
        Label _PART_ServiceNameLabel = null;
        StartStopButton _PART_ToggleButton = null;
        BackgroundWorker _bgWorker = null;

        public ServiceControl(PSE.Deployment.SetupBase.Configuration.WindowsService service)
        {
            this.SetResourceReference(ServiceControl.StyleProperty, "ServiceConfigurationStyle");

            _serviceDisplayName = service.DisplayName;
            _serviceName = service.ServiceName;

            PSE.Deployment.Util.WindowsService.ServiceInfo serviceInfo = PSE.Deployment.Util.WindowsService.GetServiceInfo(_serviceName);
            
            if (serviceInfo != null)
            {
                _bgWorker = new BackgroundWorker();
                _bgWorker.DoWork += new DoWorkEventHandler(_bgWorker_DoWork);
                _bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgWorker_RunWorkerCompleted);
            }
            else
            {
                this.Visibility = Visibility.Collapsed;
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _PART_ServiceNameLabel = base.GetTemplateChild("PART_ServiceName") as Label;
            _PART_ServiceNameLabel.Content = _serviceDisplayName;

            _PART_ToggleButton = base.GetTemplateChild("PART_ToggleButton") as StartStopButton;
            _PART_ToggleButton.Clicked += new StartStopButton.ClickedEventHandler(_PART_ToggleButton_Clicked);

            ServiceControllerStatus? status = WindowsServiceController.GetServiceStatus(_serviceName);

            _PART_ToggleButton.IsChecked = (status != null && status.Value == ServiceControllerStatus.Running);
            _PART_ToggleButton.IsProcessing = (status != null && (status.Value == ServiceControllerStatus.StartPending || status.Value == ServiceControllerStatus.StopPending));
        }

        void _PART_ToggleButton_Clicked(StartStopButton sender, ClickedEventArgs args)
        {
            bool isHoster = _serviceName.Equals("PSEServiceHoster");
            StartStopButton buttonInstance = (StartStopButton)sender;

            _PART_ToggleButton.IsProcessing = true;

            List<object> objects = new List<object>() { isHoster, _PART_ToggleButton.IsChecked };
            _bgWorker.RunWorkerAsync(objects);
        }

        void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            bool errorOccurred = false;
            try
            {
                List<object> objects = (List<object>)e.Argument;
                bool isHoster = (bool)objects[0];
                bool isChecked = (bool)objects[1];

                if (isChecked)
                {
                    errorOccurred = !WindowsServiceController.Stop(_serviceName);
                }
                else
                {
                    if (isHoster)
                        errorOccurred = !WindowsServiceController.Start(_serviceName, new string[] { "false" });
                    else
                        errorOccurred = !WindowsServiceController.Start(_serviceName);
                }
            }
            catch
            {
                errorOccurred = true;
            }

            e.Result = errorOccurred;
        }

        void _bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bool hadErrors = (bool)e.Result;
            if (!hadErrors)
            {
                _PART_ToggleButton.IsChecked = !_PART_ToggleButton.IsChecked;

                //chamar metodo que indicar que servico foi iniciado ou parado
                if (_PART_ToggleButton.IsChecked)
                    this.ServiceStarted();
                else
                    this.ServiceStoped();
            }
            else
                ConfigurationMessageBox.Show(String.Format("O serviço \"{0}\" foi iniciado e parou. Verifique o conteúdo do event viewer para maiores detalhes.", _serviceDisplayName), ConfigurationMessageBoxButton.Ok, ConfigurationMessageBoxImage.Error);

            _PART_ToggleButton.IsProcessing = false;
        }

        public delegate StartStopButton GetStartButtonHandler();
        public StartStopButton GetStartButton()
        {
            return _PART_ToggleButton;
        }


        protected virtual void ServiceStarted()
        {
        }

        protected virtual void ServiceStoped()
        {
        }
    }
}
